#include <bits/stdc++.h>

using namespace std;

struct Access {
    long long addr;
    long long size;
    long long start;
    long long duration;
};

struct IntervalSet {
    map<long long, long long> segs; // start -> end (exclusive)
    long long total = 0;

    vector<pair<long long, long long>> to_vector() const {
        vector<pair<long long, long long>> res;
        for (auto &kv : segs) {
            res.push_back(kv);
        }
        return res;
    }

    void add_interval(long long l, long long r) {
        if (l >= r) return;
        auto it = segs.lower_bound(l);
        if (it != segs.begin()) {
            auto pit = prev(it);
            if (pit->second < l) {
                // ok
            } else {
                it = pit;
            }
        }
        long long start = l;
        long long end = r;
        while (it != segs.end() && it->first <= end) {
            if (it->second < start) {
                ++it;
                continue;
            }
            start = min(start, it->first);
            end = max(end, it->second);
            total -= (it->second - it->first);
            it = segs.erase(it);
        }
        segs[start] = end;
        total += (end - start);
    }

    vector<pair<long long, long long>> remove_interval(long long l, long long r) {
        vector<pair<long long, long long>> removed;
        if (l >= r) return removed;
        auto it = segs.lower_bound(l);
        if (it != segs.begin()) {
            auto pit = prev(it);
            if (pit->second > l) it = pit;
        }
        while (it != segs.end() && it->first < r) {
            long long s = it->first;
            long long e = it->second;
            if (e <= l) {
                ++it;
                continue;
            }
            // Remove overlap [max(s,l), min(e,r))
            long long cutL = max(s, l);
            long long cutR = min(e, r);
            if (cutL >= cutR) {
                ++it;
                continue;
            }
            removed.emplace_back(cutL, cutR);
            long long original_len = e - s;
            total -= original_len;
            it = segs.erase(it);
            if (s < cutL) {
                segs[s] = cutL;
                total += (cutL - s);
            }
            if (cutR < e) {
                segs[cutR] = e;
                total += (e - cutR);
            }
            it = segs.lower_bound(cutR);
        }
        return removed;
    }

    long long usage() const {
        return total;
    }
};

vector<pair<long long, long long>> merge_intervals(vector<pair<long long, long long>> v) {
    vector<pair<long long, long long>> res;
    sort(v.begin(), v.end());
    long long curL = -1, curR = -1;
    for (auto &seg : v) {
        if (seg.first >= seg.second) continue;
        if (curL == -1) {
            curL = seg.first;
            curR = seg.second;
        } else if (seg.first <= curR) {
            curR = max(curR, seg.second);
        } else {
            res.emplace_back(curL, curR);
            curL = seg.first;
            curR = seg.second;
        }
    }
    if (curL != -1) res.emplace_back(curL, curR);
    return res;
}

vector<pair<long long, long long>> union_intervals(const vector<pair<long long, long long>> &a,
                                                   const vector<pair<long long, long long>> &b) {
    vector<pair<long long, long long>> combined = a;
    combined.insert(combined.end(), b.begin(), b.end());
    return merge_intervals(combined);
}

vector<pair<long long, long long>> subtract_intervals(const vector<pair<long long, long long>> &a,
                                                      const vector<pair<long long, long long>> &b) {
    vector<pair<long long, long long>> res;
    size_t j = 0;
    for (auto [l, r] : a) {
        long long cur = l;
        while (cur < r) {
            while (j < b.size() && b[j].second <= cur) ++j;
            long long next_cut = r;
            if (j < b.size()) next_cut = min(next_cut, b[j].first);
            if (next_cut > cur) res.emplace_back(cur, next_cut);
            if (j >= b.size() || b[j].first >= r) break;
            cur = max(cur, b[j].second);
        }
    }
    return res;
}

struct OperationLogger {
    struct Entry {
        long long t;
        long long seq;
        string text;
    };
    vector<Entry> logs;
    long long seq = 0;

    void emit_reload(long long t, long long addr, long long size) {
        logs.push_back({t, seq++, "Reload " + to_string(t) + " " + to_string(addr) + " " + to_string(size)});
    }
    void emit_offload(long long t, long long addr, long long size) {
        logs.push_back({t, seq++, "Offload " + to_string(t) + " " + to_string(addr) + " " + to_string(size)});
    }
    void emit_visit(long long t, int idx) {
        logs.push_back({t, seq++, "Visit " + to_string(t) + " " + to_string(idx)});
    }
    void emit_fin(long long t) {
        logs.push_back({t, seq++, "Fin " + to_string(t)});
    }

    void flush() {
        sort(logs.begin(), logs.end(), [](const Entry &a, const Entry &b) {
            if (a.t != b.t) return a.t < b.t;
            return a.seq < b.seq;
        });
        for (auto &e : logs) cout << e.text << '\n';
    }
};

long long total_length(const vector<pair<long long, long long>> &segs) {
    long long total = 0;
    for (auto &seg : segs) {
        total += max(0LL, seg.second - seg.first);
    }
    return total;
}

struct RunningVisit {
    long long finish;
    vector<pair<long long, long long>> intervals;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    long long L, M;
    int N;
    if (!(cin >> L >> M >> N)) return 0;
    vector<Access> req(N);
    for (int i = 0; i < N; ++i) {
        cin >> req[i].addr >> req[i].size >> req[i].start >> req[i].duration;
    }

    vector<vector<pair<long long, long long>>> req_required(N);
    for (int i = 0; i < N; ++i) {
        req_required[i] = {{req[i].addr, req[i].addr + req[i].size}};
    }

    vector<vector<int>> groups;
    vector<vector<pair<long long, long long>>> group_required;
    for (int i = 0; i < N; ) {
        vector<int> g;
        vector<pair<long long, long long>> needed;
        long long start_time = req[i].start;
        int j = i;
        while (j < N && req[j].start == start_time) {
            g.push_back(j);
            needed.emplace_back(req[j].addr, req[j].addr + req[j].size);
            ++j;
        }
        groups.push_back(g);
        group_required.push_back(merge_intervals(needed));
        i = j;
    }

    int G = groups.size();
    vector<vector<pair<long long, long long>>> future_required(G);
    vector<pair<long long, long long>> future_union;
    for (int gi = G - 1; gi >= 0; --gi) {
        future_required[gi] = future_union;
        future_union = union_intervals(future_union, group_required[gi]);
    }

    IntervalSet loaded;
    OperationLogger logger;
    long long io_time = 0;
    long long barrier = 0;
    vector<RunningVisit> running;

    auto cleanup_running = [&](long long now) {
        running.erase(remove_if(running.begin(), running.end(), [&](const RunningVisit &rv) {
            return rv.finish <= now;
        }), running.end());
    };

    auto active_intervals = [&]() {
        vector<pair<long long, long long>> acc;
        for (auto &rv : running) {
            acc.insert(acc.end(), rv.intervals.begin(), rv.intervals.end());
        }
        return merge_intervals(acc);
    };

    for (int gi = 0; gi < G; ++gi) {
        const auto &group = groups[gi];
        auto order = group;
        sort(order.begin(), order.end(), [&](int a, int b) {
            if (req[a].addr != req[b].addr) return req[a].addr > req[b].addr;
            return a > b;
        });

    long long group_finish = barrier;
    vector<pair<long long, long long>> reserved_group;
    vector<int> visit_order;

        for (int idx : order) {
            const auto &required = req_required[idx];
            long long need_size = total_length(required);
            if (need_size > M) {
                cerr << "Task requires " << need_size << " bytes > capacity " << M << "\n";
                return 1;
            }

            cleanup_running(io_time);

            auto current = loaded.to_vector();
            auto to_load = subtract_intervals(required, current);
            long long load_bytes = total_length(to_load);
            long long extra_needed = max(0LL, loaded.usage() + load_bytes - M);

            while (extra_needed > 0) {
                cleanup_running(io_time);
                auto protected_now = union_intervals(required, reserved_group);
                protected_now = union_intervals(protected_now, active_intervals());
                current = loaded.to_vector();
                auto removable = subtract_intervals(current, protected_now);
                if (removable.empty()) {
                    if (running.empty()) {
                        cerr << "Unable to free enough memory despite required size within capacity" << '\n';
                        return 1;
                    }
                    long long next_release = running.front().finish;
                    for (auto &rv : running) {
                        next_release = min(next_release, rv.finish);
                    }
                    if (next_release <= io_time) next_release = io_time + 1;
                    io_time = next_release;
                    cleanup_running(io_time);
                    continue;
                }
                for (auto &seg : removable) {
                    long long l = seg.first;
                    long long r = seg.second;
                    while (extra_needed > 0 && l < r) {
                        long long take = min(extra_needed, r - l);
                        auto removed = loaded.remove_interval(l, l + take);
                        long long freed = 0;
                        for (auto &part : removed) {
                            long long len = part.second - part.first;
                            if (len <= 0) continue;
                            logger.emit_offload(io_time, part.first, len);
                            io_time += 40LL * len;
                            freed += len;
                        }
                        if (freed == 0) break;
                        extra_needed -= freed;
                        l += freed;
                    }
                    if (extra_needed <= 0) break;
                }
            }

            current = loaded.to_vector();
            to_load = subtract_intervals(required, current);
            for (auto &seg : to_load) {
                long long len = seg.second - seg.first;
                if (len <= 0) continue;
                logger.emit_reload(io_time, seg.first, len);
                io_time += 40LL * len;
                loaded.add_interval(seg.first, seg.second);
            }

            reserved_group = union_intervals(reserved_group, required);
            visit_order.push_back(idx);
        }

        long long visit_start = max({barrier, req[group.front()].start, io_time});
        for (int idx : visit_order) {
            logger.emit_visit(visit_start, idx);
            long long visit_end = visit_start + req[idx].duration;
            group_finish = max(group_finish, visit_end);
            running.push_back({visit_end, req_required[idx]});
        }

        barrier = max(barrier, group_finish);
    }

    long long finish_time = max(barrier, io_time);
    logger.emit_fin(finish_time);
    logger.flush();
    return 0;
}
